package com.raidpoints.client;

import java.util.ArrayList;

import com.google.gwt.cell.client.AbstractCell;
import com.google.gwt.cell.client.ActionCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.safehtml.shared.SafeHtmlBuilder;
import com.google.gwt.user.cellview.client.CellTable;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.SimplePager;
import com.google.gwt.user.cellview.client.ColumnSortEvent.ListHandler;
import com.google.gwt.user.cellview.client.HasKeyboardSelectionPolicy.KeyboardSelectionPolicy;
import com.google.gwt.user.cellview.client.SimplePager.TextLocation;
import com.google.gwt.user.cellview.client.TextColumn;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CheckBox;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.DockLayoutPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SingleSelectionModel;

public class AccountPage extends Composite{
	RaidPoints rp;
	DockLayoutPanel dp;
	String name;
	CellTable<character> charTable;
	CellTable<event> eventTable;
	AccountPage ap;
	boolean noselect;
	int myacc;
	CheckBox miltime;
	Button permButton;

	ListDataProvider<character> chardataProvider;
	SingleSelectionModel<character> charselectionModel;
	ListDataProvider<event> eventdataProvider;
	SingleSelectionModel<event> eventselectionModel;
	SimplePager simplePager;

	AccountPage(RaidPoints mrp, String mname){
		this(mrp,mname,-1);
	}

	AccountPage(RaidPoints mrp,String mname,int cid){
		rp = mrp;
		ap = this;
		myacc = cid;
		name = mname;
		noselect = false;
		dp = new DockLayoutPanel(Unit.EM);
		initWidget(dp);
		HTML banner = new HTML("<font size=\"3\">Account: " + name + " Details:</font>");
		dp.addNorth(banner, 3);

		HorizontalPanel confPan = new HorizontalPanel();
		Button refreshButton = new Button("Refresh");
		confPan.add(refreshButton); 
		refreshButton.addClickHandler(new ClickHandler(){
			@Override
			public void onClick(ClickEvent event) {
				Refresh();				
			}
		});
		if(myacc < 0){
			Button addCharButton = new Button("Add Character");
			Button removeCharButton  = new Button("Remove Character");
			Button notSettingsButton = new Button("Notification Settings");
			Button changepassButton = new Button("Change Pass");
			miltime = new CheckBox("Use Standard Time");
			if(!rp.mil) miltime.setValue(true);
			confPan.add(addCharButton); confPan.add(removeCharButton); confPan.add(notSettingsButton);
			confPan.add(changepassButton); confPan.add(miltime);

			banner.addClickHandler(new ClickHandler(){

				@Override
				public void onClick(ClickEvent event) {
					if(rp.auth != RaidPoints.AuthType.admin) return;
					AdminBox ab = new AdminBox(rp);
					ab.center(); ab.show();
				}

			});


			addCharButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					AddCharacterBox cb = new AddCharacterBox(ap);	
					cb.center(); cb.show();
				}
			});

			removeCharButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					RemoveCharacterBox cb = new RemoveCharacterBox(ap);	
					cb.center(); cb.show();
				}
			});

			notSettingsButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					NoteBox nb = new NoteBox(rp);
					nb.center(); nb.show();
				}
			});

			changepassButton.addClickHandler(new ClickHandler(){
				@Override
				public void onClick(ClickEvent event) {
					ChangePassBox cpb = new ChangePassBox(rp);
					cpb.center(); cpb.show();
				}
			});

			miltime.addValueChangeHandler(new ValueChangeHandler<Boolean>(){
				@Override
				public void onValueChange(ValueChangeEvent<Boolean> event) {
					if(event.getValue()) rp.mil = false;
					else rp.mil = true;
					rp.rpsvc.SetMilTime((rp.mil ? 0 : 1), rp.stringCallback);
					Widget w = rp.navmap.get(rp.eventItem);
					if(w instanceof RaidCalendar) ((RaidCalendar) w).ChangeTime();
					((RaidPoints.HasRedraw) w).Redraw();
					Refresh();
				}
			});

		}
		else{ //not my account
			if(rp.auth == RaidPoints.AuthType.admin){
				permButton = new Button("Permissions");
				confPan.add(permButton);
				permButton.addClickHandler(new ClickHandler(){
					@Override
					public void onClick(ClickEvent event) {
						AccountPermBox apb  = new AccountPermBox(rp,name,myacc);
						apb.center(); apb.show();
					}
				});
			}
		}

		dp.addNorth(confPan, 3);

		ScrollPanel charPan = new ScrollPanel();
		charTable = new CellTable<character>();
		chardataProvider = new ListDataProvider<character>();
		charselectionModel = new SingleSelectionModel<character>();
		charTable.setSize("100%", "100%");
		charTable.setPageSize(20);
		charTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		charPan.add(charTable);
		dp.addNorth(charPan, 20);

		chardataProvider.addDataDisplay(charTable);
		charTable.setSelectionModel(charselectionModel);

		charselectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler(){
			public void onSelectionChange(SelectionChangeEvent event) {
				character selected = charselectionModel.getSelectedObject();
				if(selected != null){
					if(noselect) noselect = false;
					else rp.ViewChar(selected);
					charselectionModel.setSelected(selected,false);
				}	

			}	
		});

		Column<character,character> gameCol = new Column<character,character>(new GameCell()){

			@Override
			public character getValue(character object) {
				return object;
			}

		};
		charTable.addColumn(gameCol);
		charTable.setColumnWidth(gameCol, "16px");

		TextColumn<character> nameCol = new TextColumn<character>(){

			@Override
			public String getValue(character object) {
				return object.name;
			}

		};
		charTable.addColumn(nameCol,"Name");

		//		TextColumn<character> classCol = new TextColumn<character>(){
		//
		//			@Override
		//			public String getValue(character object) {
		//				return object.Class;
		//			}
		//			
		//		};
		//		charTable.addColumn(classCol,"Class");

		Column<character,character> classCol = new Column<character,character>(new ClassCell()){

			@Override
			public character getValue(character object) {
				return object;
			}

		};
		charTable.addColumn(classCol,"Class");

		TextColumn<character> roleCol = new TextColumn<character>(){

			@Override
			public String getValue(character object) {
				return object.prole;
			}

		};
		charTable.addColumn(roleCol,"Primary Role");

		TextColumn<character> sroleCol = new TextColumn<character>(){

			@Override
			public String getValue(character object) {
				if(object.srole == null) return "";
				StringBuilder sb= new StringBuilder();
				for(int i = 0; i < object.srole.size(); i++) sb.append((i > 0 ? ", " : "") + object.srole.get(i));
				return sb.toString();
			}

		};
		charTable.addColumn(sroleCol,"Secondary Roles");

		TextColumn<character> serverCol = new TextColumn<character>(){

			@Override
			public String getValue(character object) {
				return object.server;
			}

		};
		charTable.addColumn(serverCol,"Server");

		if(myacc < 0){

			ActionCell<character> modCell = new ActionCell<character>("Mod", new ActionCell.Delegate<character>(){
				@Override
				public void execute(character object) {
					noselect = true;
					AddCharacterBox ac = new AddCharacterBox(ap,object,rp);
					ac.center(); ac.show();
				}
			});

			Column<character,character> charmodColumn = new Column<character,character>(modCell){

				@Override
				public character getValue(character object) {
					return object;
				}

			};

			charTable.addColumn(charmodColumn);
		}

		HorizontalPanel econfPan = new HorizontalPanel();


		ScrollPanel eventPan = new ScrollPanel();
		eventTable = new CellTable<event>();

		HTML banner2 = new HTML("<font size=\"3\">Raids:</font>");
		SimplePager.Resources pagerResources = GWT.create(SimplePager.Resources.class);
		simplePager = new SimplePager(TextLocation.CENTER,pagerResources,false,0,true);
		simplePager.setDisplay(eventTable);
		econfPan.add(banner2); econfPan.add(simplePager);
		dp.addNorth(econfPan, 3);


		eventdataProvider = new ListDataProvider<event>();
		eventselectionModel = new SingleSelectionModel<event>();
		eventTable.setSize("100%", "100%");
		eventTable.setPageSize(15);
		eventTable.setKeyboardSelectionPolicy(KeyboardSelectionPolicy.ENABLED);
		eventPan.add(eventTable);
		dp.add(eventPan);

		eventdataProvider.addDataDisplay(eventTable);
		eventTable.setSelectionModel(eventselectionModel);

		TextColumn<event> startCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				return object.starttime.getFullDate(rp.mil);
			}
		};
		eventTable.addColumn(startCol,"Start");


		TextColumn<event> destCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				if(object.game.equals("")) return object.note.split(":;:")[0];
				else if(object.creator == 0) return object.dest;
				else return object.game + " - " + object.dest;
			}
		};
		eventTable.addColumn(destCol,"Destination");

		TextColumn<event> noteCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				if(object.game.equals("")) return object.note.split(":;:")[1];
				else return object.note;
			}
		};
		eventTable.addColumn(noteCol,"Note");

		TextColumn<event> mynoteCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				return object.mynote;
			}
		};
		eventTable.addColumn(mynoteCol,"My Note");

		TextColumn<event> charCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				return object.charname;
			}
		};
		eventTable.addColumn(charCol,"Character");

		TextColumn<event> slotroleCol = new TextColumn<event>(){
			@Override
			public String getValue(event object) {
				return object.slotrole;
			}
		};
		eventTable.addColumn(slotroleCol,"Role");

		//		TextColumn<event> slottingCol = new TextColumn<event>(){
		//			@Override
		//			public String getValue(event object) {
		//				return object.attend;
		//			}
		//		};
		Column<event,event> slottingCol = new Column<event,event>(new SlotCell()){

			@Override
			public event getValue(event object) {
				return object;
			}

		};
		eventTable.addColumn(slottingCol,"Slotting");

		if(myacc < 0){

			MyActionCell signcell = new MyActionCell("Mod",new ActionCell.Delegate<event>(){

				@Override
				public void execute(event object) {
					ModSignupBox sb = new ModSignupBox(ap,object);
					sb.center(); sb.show();
					noselect = true;
				}

			});

			Column<event,event> signCol = new Column<event,event>(signcell){

				@Override
				public event getValue(event object) {
					return object;
				}

			};
			eventTable.addColumn(signCol,"");
		}


		eventselectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler(){
			public void onSelectionChange(SelectionChangeEvent event) {
				event selected = eventselectionModel.getSelectedObject();
				if(selected != null){
					if(noselect) noselect = false;
					else{
						for(event e : rp.dataProvider.getList()){
							if(e.eid == selected.eid){
								rp.ViewPoints(e);
								break;
							}
						}
						//	rp.ViewPoints(selected);
					}
					eventselectionModel.setSelected(selected,false);
				}	

			}	
		});


		Refresh();
	}

	void Refresh(){
		eventdataProvider.getList().clear();
		chardataProvider.getList().clear();
		charTable.setRowCount(0);
		eventTable.setRowCount(0);

		AsyncCallback<ArrayList<character>> charCallback = new AsyncCallback<ArrayList<character>>(){

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
			}

			@Override
			public void onSuccess(ArrayList<character> result) {
				if(result == null) return;
				chardataProvider.getList().clear();
				chardataProvider.getList().addAll(result);
				charTable.setRowCount(result.size());
			}

		};

		rp.rpsvc.GetAccountChars(myacc, charCallback);

		AsyncCallback<ArrayList<event>> eventCallback = new AsyncCallback<ArrayList<event>>(){

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onSuccess(ArrayList<event> result) {
				if(result == null) return;
				eventdataProvider.getList().clear();
				eventdataProvider.getList().addAll(result);
				eventTable.setRowCount(result.size());
				simplePager.firstPage();
				if(myacc<1){
					for(event e : result){
						for(event ee : rp.dataProvider.getList()){
							if(ee.eid == e.eid){
								//GWT.log("setting " + ee.starttime.getDate() + " to " + e.attend);
								if(!ee.attend.equals("slotted") || (e.attend.equals("slotted"))) ee.attend = e.attend;
								break;
							}
						}
					}
					((RaidPoints.HasRedraw) rp.navmap.get(rp.eventItem)).Redraw();
				}
			}

		};

		rp.rpsvc.GetAccountEvents(myacc, eventCallback);
	}

	public class SlotCell extends AbstractCell<event>{

		@Override
		public void render(com.google.gwt.cell.client.Cell.Context context,
				event value, SafeHtmlBuilder sb) {
			String color = "#8997A5";
			if(value.attend.equals("signedup")) color = "#668CD9";
			else if(value.attend.equals("standby")) color = "#A992A9";
			else if(value.canceled) color = "red";
			else if(value.attend.equals("slotted")) color = "#4CB052";	
			if(value.canceled) color = "red";
			sb.appendHtmlConstant("<table bgcolor=\"" + color + "\"><tr><td>" + "<font color=\"white\">" + (value.canceled ? "canceled" : value.attend) + "</font></td></tr></table>");
		}

	}

	public class GameCell extends AbstractCell<character>{

		@Override
		public void render(com.google.gwt.cell.client.Cell.Context context,
				character value, SafeHtmlBuilder sb) {
			if(value.ngsid == 1){
				sb.appendHtmlConstant("<img src=\"cicons/battletag.png\" width=\"20\" height=\"20\">");
			}
			else{
				String gi = "";
				if(value.gid == 1) gi = "wow.png";
				else if(value.gid == 2) gi = "swtor.png";
				else if(value.gid == 5) gi = "rift.png";
				sb.appendHtmlConstant("<img src=\"cicons/" + gi + "\" width=\"20\" height=\"20\">");	
			}
		}

	}

	public class ClassCell extends AbstractCell<character>{

		@Override
		public void render(com.google.gwt.cell.client.Cell.Context context,
				character value, SafeHtmlBuilder sb) {
			if(value.ngsid == 0) sb.appendHtmlConstant("<img src=\"cicons/" + RaidPoints.GetCicon(value) + ".png\" width=\"20\" height=\"20\">&nbsp;" + value.Class);	
			else sb.appendHtmlConstant(value.Class);
		}

	}
	
	public class MyModCell extends ActionCell<character>{

		public MyModCell(String text,com.google.gwt.cell.client.ActionCell.Delegate<character> delegate) {
			super(text, delegate);
			// TODO Auto-generated constructor stub
		}
		
		@Override
		public void render(Context context, character value, SafeHtmlBuilder sb){
			if(value.ngsid == 0) super.render(context, value, sb);
		}

	};

	public class MyActionCell extends ActionCell<event>{

		public MyActionCell(String text,
				com.google.gwt.cell.client.ActionCell.Delegate<event> delegate) {
			super(text, delegate);
			// TODO Auto-generated constructor stub
		}

		@Override
		public void render(Context context, event value, SafeHtmlBuilder sb) {
			if(!value.over) super.render(context,value,sb);


		}


	};
}
